#region NeoPatterns
// 
// NeoPatterns framework is released under LGPLv3 license.
// See http://www.opensource.org/licenses/lgpl-3.0.html for more details.
// 
// Please visit http://neopatterns.wikidot.com for more information about NeoPatterns
// 
// Copyright (c) Pascal Craponne 2008
// 
#endregion

using System;
using System.Collections.Generic;

namespace NeoPatterns.Core.Registry
{
    /// <summary>
    /// Exposes object factory
    /// </summary>
    public interface IObjectRegistry
    {
        /// <summary>
        /// Object getter. May create and initialize object.
        /// Creation and Initialization are separated to help used avoiding deadlocks
        /// </summary>
        /// <param name="objectName"></param>
        /// <returns></returns>
        object Get(string objectName);

        /// <summary>
        /// Object getter, generic version
        /// </summary>
        /// <typeparam name="T">Request type</typeparam>
        /// <param name="objectName">Object name</param>
        /// <returns></returns>
        T Get<T>(string objectName);

        /// <summary>
        /// Returns all object names matching a given type
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        IList<string> GetNamesForType(Type type);

        /// <summary>
        /// Returns all object names matching a given type, generic version
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IList<string> GetNamesForType<T>();

        /// <summary>
        /// Registers an object as interceptor
        /// </summary>
        /// <param name="pointcutSelectorRef"></param>
        /// <param name="advisorRef"></param>
        void RegisterAspect(Ref pointcutSelectorRef, Ref advisorRef);

        /// <summary>
        /// Register an object definition
        /// </summary>
        /// <param name="objectName">Object unique name</param>
        /// <param name="type">Object type</param>
        /// <param name="instance">Instance: true for creation at each call, false for singleton</param>
        /// <param name="creator">Creation delegate (object creator(IObjectRegistry objectRegistry))</param>
        /// <param name="initializer">Initialization delegate (void initializer(object o,IObjectRegistry objectRegistry)</param>
        void RegisterDefinition(string objectName, Type type, IList<Ref> advisors, bool instance, Delegate creator, Delegate initializer);

        /// <summary>
        /// Creates a child IObjectRegistry, inheriting objects from parent.
        /// </summary>
        /// <returns></returns>
        IObjectRegistry CreateChild();

        /// <summary>
        /// Initializes an object with dependencies
        /// This method is useful when objects are already created (forms, web pages) 
        ///         and just need to be injected
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="objectType"></param>
        void Initialize(object instance, Type objectType);
    }
}